<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Pico Web Remoting</title>
<style type="text/css">
<!--
.style1 {font-family: "Courier New", Courier, monospace}
-->
</style>
</head>
<body>
<p>Pico Web Remoting (PWR) allows web requests to be bounded
directly to methods in a class. All public methods are eligible, and
method parameters are pulled from query-string or form post-fields for
invocation. PWR is not a page technology as such, as it uses AJAX
invoation of methods on the server side. As such you most likely going
to use this technology from JavaScript, with a library like <a
    href="http://jquery.com/">jQuery</a> that makes calling server-side
functions that return <a href="http://www.json.org/">JSON</a> replies
easy.</p>
<span class="callout">Every Object gets a URL !</span>
<p>We have tried to make PWR <strong>as transparent as
possible</strong>. Thus objects that can be published via PWR, are POJOs. It is
up to you whether you interface/impl separate them, but be reminded that
by default all public methods will be published. As with all of the
PicoContainer Web technologies, you will decide which scope a component
belongs in - application, session or request - and compose them
accordingly.</p>
<p>Publishing class and method names direct to the web, is alluring, but it is also dangerous. Do not think of this as publishing a domain model to the web, it is really a way for you to markup contacts in plain Java. It also suggests that you are going to want to have a different package, class and method naming design for the objects your publishing with PWR. Read about the example, then read Naming Considerations below</p>
<h2>Example webapp : Simple email package.</h2>
<p>We forked an example of jQuery and Java together made for an IBM
AlphaWorks article: <a href="http://www.ibm.com/developerworks/web/library/wa-jquery1/">Working with jQuery, Part 1: Bringing desktop applications to the browser</a>. The original had a custom servlet to
decode requests, invoke methods and craft JSON replies. We've
essentially deleted that servlet and leveraged PWR instead.</p>
<h3>Binding objects to URLs - how it works</h3>
<p>In the demo webapp there a 'send' method on a class called 'Sent'.
The class name and method name are encoded in the URL. The method
parameters are pulled from the form post fields, and the reply is a JSON
representation of the methods return type. Here are some screenshots
from a Firefox plugin called <a href="https://addons.mozilla.org/en-US/firefox/addon/6647">HttpFox</a> and how the web request maps to
the source method.  The case in question is for the 'send' function of the Simple email app: </p>
<p><img src="images/PWR-POST.png" alt="post" name="post" width="871"
    height="1296" id="post" /></p>
<p>MessageData is just a POJO:</p>
<p><img src="images/PWR-POST-MessageData.png" alt="post" name="post" width="803"
    height="667" id="post" /></p>
<p>A GET invocation is quite similar. Instead of form post-fields
the method parameters are mapped to query string parameters.</p>
<h3>Exceptions</h3>
<p>If PWR encounters an exception during the processing of a method
invocation, it takes the message text and makes it available to the
client in the following style:</p>
<div class="source"><pre>
{
  "ERROR": true,
  "message": "no such message ID"
}
</pre></div>
<h2>Doing the scoped Dependency Injection setup.</h2>
<p>Composition of the webapp is done in an implementation of
  WebappComposer, like so:</p>
<div class="source">
  <pre>
package org.picocontainer.web.sample.ajaxemail;

import org.picocontainer.web.WebappComposer;
import static org.picocontainer.web.StringFromRequest.addStringRequestParameters;
import static org.picocontainer.web.IntFromRequest.addIntegerRequestParameters;
import org.picocontainer.MutablePicoContainer;
import static org.picocontainer.Characteristics.USE_NAMES;

public class AjaxEmailWebappComposer implements WebappComposer {


    // These will be cached and shared for all sessions unless otherwise specified

    public void composeApplication(MutablePicoContainer appContainer) {
        appContainer.addComponent(MessageStore.class, InMemoryMessageStore.class);
    }


    // These components can depend on each other or those from the application scope
    // They will also be cached per session unless otherwise specified

    public void composeSession(MutablePicoContainer sessionContainer) {
        // stateless
    }


    // These components can depend on each other or those from the session scope
    // They will also be cached per session unless otherwise specified

    public void composeRequest(MutablePicoContainer requestContainer) {

        // User is specified in a Cookie (after signin obviously)
        requestContainer.addAdapter(new User.FromCookie());

        // Regular components. The public methods for which are published remotely
        requestContainer.as(USE_NAMES).addComponent(Auth.class);
        requestContainer.as(USE_NAMES).addComponent(Inbox.class);
        requestContainer.as(USE_NAMES).addComponent(Sent.class);
    }

}
</pre>
</div>
<p>In the above there is a single application-scoped component, InMemoryMessageStore,
  for all users/sessions and requests to share. All
  other components are added at request scope, meaning they are only
  instantiated at the time of request and only if they are needed. The
  major components are Auth, Inbox and Sent. They have their public
  methods made available. Inbox and Sent methods are effectively not
  available until login has been performed via the Auth class. Once you
  have logged in, a cookie is set, thus User.FromCookie (a Provider)
  allows access to that. The parameters for the methods in Auth, Inbox and
  Send are made available via the addStringRequestParameters(..) and
  addIntegerRequestParameters(..) methods. These set up multiple Injectors
  for to allow the binding by name of things from query-string parameters
  or form post-fields.</p>
<p><span class="callout">Convention over Configuration !</span></p>
<p>PicoContainer Web Remoting(by default) does not have XML files like Spring, JBoss or XWork (Struts2). It also tries to be as transparent as possible - there are are no base classes to extend, no interfaces to implement, and no mandatory annotations, no bean definitions, no URL mappings, no property assignments - you just call methods on components from a web page in JavaScript. This makes it easy to test components in plain unit tests too.</p>
<p>Here is an fairly standard web.xml for a PicoWebRemoting
  webapp:</p>
<div class="source">
  <pre>
	<web-app>
	  <display-name>Pico Web Remoting Demo</display-name>

	  <context-param>
	    <param-name>webapp-composer-class</param-name>
	    <param-value>org.picocontainer.web.sample.ajaxemail.JQueryDemoWebappComposer</param-value>
	  </context-param>

	  <filter>
	    <filter-name>pwrFilter</filter-name>
        <filter-class>org.picocontainer.web.remoting.PicoWebRemotingServlet$ServletFilter</filter-class>
	  </filter>

	  <filter-mapping>
	    <filter-name>pwrFilter</filter-name>
	    <url-pattern>/pwr/*</url-pattern>
	  </filter-mapping>

	  <listener>
        <listener-class>org.picocontainer.web.PicoServletContainerListener</listener-class>
	  </listener>

      <servlet>
        <servlet-name>pwrServlet</servlet-name>
        <servlet-class>org.picocontainer.web.remoting.JsonPicoWebRemotingServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>scopes_to_publish</param-name>
            <param-value>session,request</param-value>
        </init-param>
        <init-param>
            <param-name>package_prefix_to_strip</param-name>
            <param-value>org.picocontainer.web.sample.ajaxemail</param-value>
        </init-param>
      </servlet>

      <servlet-mapping>
        <servlet-name>pwrServlet</servlet-name>
        <url-pattern>/pwr/*</url-pattern>
      </servlet-mapping>

	  <welcome-file-list>
	    <welcome-file>index.html</welcome-file>
	  </welcome-file-list>

	</web-app>


</pre>
</div>
<h3>Limiting Scopes to Publish</h3>
<p>In the web.xml file, you can specify a 'scopes_to_publish'
  element that takes a comma separated list of scopes. One or more of
  'application' , 'session' and 'request' (without the quotes). This
  listed will be analysed for publication as PWR invocable.</p>
<h3>Limiting HTTP Methods for a Class' Methods</h3>
<p>Only public method on components managed by PicoContainer are
  eligible. By default, all web methods (GET, POST, PUT, DELETE) are
  possible for a matching method. However there are annotations (in
  package org.picocontainer.web) with  names @GET, @POST, @PUT, @DELETE, that restrict down
  possibilities. If you want a component's method to be only available for
  POST, put a @POST annotation above it. If you have a public method that you do not want to publish in a component that is otherwise published, use @NONE.</p>
<h3>Shortening URLs to objects.</h3>
<p>PWR by default will encode the whole class name including
  package. All dots in the package name are changed to slashes to make
  apparent directories, and the case of the Class name itself is
  preserved. With a web.xml element called <span class="style1">package_prefix_to_strip</span> it is
  possible to eliminate a prefix for all of the objects published. Thus,
  you could essentially turn
  <span class="style1">http://mycompany.com/r/com/mycompany/store/Cart/buy</span> into
  <span class="style1">http://mycompany.com/r/store/Cart/buy</span> if you wanted.  The /r/ prefix is the mapping to the servlet that is configured in the 
  web.xml - it could just as easily be /pwr/ or /rpc/ or /ajax/ </p>
<h3>Mapping to a Suffix</h3>
<p>You can have a suffix such as .ajax or .json at the end the method name. For example <span class="style1">http://mycompany.com/r/com/mycompany/store/Cart/buy.json</span> might be what you want. There is an servlet init-param for the servlet in web.xml element called <span class="style1">suffix_to_strip</span> that would specify '.json' in this case.</p>
<h3>Lower case Class names in path</h3>
<p>In our example above Auth (the class) appears as 'Auth' in any URLs.  If you specify an init parameter of 'lower_case_path' as true, then you can have it as 'auth' in URLs</p>
<h3>Cross-site request forgery (CSRF) protection</h3>
<p>Many AJAX capable technologies are vulnerable to CSRF attacks.
PWR is no different. If you are running your webapp publically, and there
are functions that could be valuable for a hacker to invoke simulating
genuine user action, you will want to guard them. With PWR, you would
set something in the page, that would be send back to the server with
each AJAX request. The Guard class would be instantiated before the
potentially vulnerable method would be invoked. The guard class would be
instantiated and depend on the guard parameter, ensuring that it could
be verified and that an exception could be thrown:</p>
<div class="source">
<pre>requestContainer.addComponent("guard", MyGuard.class);
requestContainer.as(GUARD, USE_NAMES).addComponent(VulnerableThing.class);
</pre></div>

<h2>Explicit dependance on parameters from HTTP request</h2>
<p>Binding to parameter from the HTTP Request is implicit as long as you use as(USE_NAMES) when adding components.
    If you the range of parameter names to be explicit, do the following in WebappComposition class</p>
<div class="source">
<pre>
// these are pulled from query-strings (GET) or form-fields (POST)
addStringRequestParameters(requestContainer,
        &quot;to&quot;, &quot;subject&quot;, &quot;message&quot;, &quot;view&quot;,
        &quot;userName&quot;, &quot;password&quot;, &quot;userId&quot;, &quot;sec&quot;);

addIntegerRequestParameters(requestContainer, &quot;msgId&quot;);
</pre></div>

<h2>Naming considerations.</h2>
<p>Consider the this URL: <span class="style1">http://mycompany.com/r/com/mycompany/store/ShoppingCart/addToCart</span></p>
<p>It is what would result from a Java class called ShoppingCart with a method called addToCart (in package com.mycompany.store). Java is often long winded like this. You are going to want to change the rules when working with PWR. ShoppingCart can be shortened to Cart as it is clear being in a directory (package) 'store' what it is. Method 'addToCart' is also too verbose if we consider the URL and the implicit association with 'Cart'. Thus 'buy' might be clearer intent. </p>
<p>In short, when naming packages, classes and methods for PWR, you should think about contracts between the client and the server app, and not simply publishing preexisting names.</p>
<p>It is also the case that you can only have one method of a particular name that is public, otherwise PWR will not know which ne to invoke for incoming requests.</p>
<h2>Further reading.</h2>
<p>The Maven based example project can be checked out with
  Subversion from <a
    href="http://svn.codehaus.org/picocontainer/java/2.x/trunk/web/examples/ajax-email/">here</a>.</p>
<h2>Downloading.</h2>
<p>See <a href="downloads.html">downloads</a> on how to download the
Pico Web Remoting jar either using Maven or by downloading the full
distribution.</p>
</body>
</html>